package base.living;

import java.awt.Point;
import java.awt.Rectangle;

import base.collision.Collision;
import base.common.IBoundingBox;
import base.common.ILiving;
import base.world.World;

public class EntityUtil
{
	public static double distXToRot(double par1, int par2)
	{
		return Math.cos(par1 * Math.PI / 180) * par2;
	}

	public static double distYToRot(double par1, int par2)
	{
		return -Math.sin(par1 * Math.PI / 180) * par2;
	}

	public static double distToPos(int par1, int par2, int par3, int par4)
	{
		return Math.sqrt(Math.pow(par1 - par3, 2) + Math.pow(par2 - par4, 2));
	}

	public static double rotToPos(int par1, int par2, int par3, int par4)
	{
		return rotBound(Math.toDegrees(Math.atan2(par2 - par4, par3 - par1)));
	}

	public static double rotToRot(double par1, double par2)
	{
		double i = par2 - par1;
		return i + (i < -180F ? 360 : i < 180F ? -360 : 0);
	}

	public static double rotBound(double par1)
	{
		return (par1 + 360) % 360;
	}

	/**Get smooth rotation to target angle
	 * @param par1 - current rotation
	 * @param par2 - target rotation
	 * @param par3 - speed
	 * @param par4 - range
	 * @return rotation
	 */
	public static double rotToRotWithSpeed(double par1, double par2, int par3, int par4)
	{
		double i = 0;
		double j = par1;

		for(int k = 0; k < par3; k++)
		{
			i = par2 - j;
			i += i < -180D ? 360D : i > 180D ? -360D : 0D;

			if (i < -par4)
			{
				j -= 1D;
			}
			if (i > par4)
			{
				j += 1D;
			}

			j = rotBound(j);
		}

		return j;
	}

	/**Returns true if no entities intersects shifted par2IBoundingBox
	 * @param par1World
	 * @param par2IBoundingBox
	 * @param par3
	 * @param par4
	 * @return
	 */
	public static boolean isCollisionDirectionEmptyOfEntity(World par1World, IBoundingBox par2IBoundingBox, float par3, int par4)
	{
		if (par2IBoundingBox == null)
		{
			return false;
		}

		Rectangle boundingbox = (Rectangle) par2IBoundingBox.getBoundingBox().clone();
		boundingbox.setLocation(boundingbox.x + (int) EntityUtil.distXToRot(par3, par4), boundingbox.y + (int) EntityUtil.distYToRot(par3, par4));

		for (ILiving iliving : par1World.livingList)
		{
			if (iliving instanceof Entity && iliving != par2IBoundingBox && Collision.isCollideWith(((Entity) iliving), boundingbox))
			{
				return false;
			}
		}

		return true;
	}

	public static Point getPointOutOfEntity(World par1World, IBoundingBox par2IBoundingBox, int par3)
	{
		if (par2IBoundingBox == null)
		{
			return null;
		}

		Rectangle boundingbox = (Rectangle) par2IBoundingBox.getBoundingBox().clone();
		Point point = new Point(boundingbox.x, boundingbox.y);
		Point point1 = new Point(boundingbox.x, boundingbox.y);

		for (ILiving iliving : par1World.livingList)
		{
			if (iliving instanceof Entity && iliving != par2IBoundingBox)
			{
				Rectangle boundingbox1 = ((Entity) iliving).getBoundingBox();
				
				while(boundingbox.intersects(boundingbox1) && distToPos(point.x, point.y, point1.x, point1.y) < par3)
				{
					if (boundingbox.x > boundingbox1.x)
					{
						boundingbox.x++;
					}
					else if (boundingbox.x < boundingbox1.x)
					{
						boundingbox.x--;
					}

					if (boundingbox.y > boundingbox1.y)
					{
						boundingbox.y++;
					}
					else if (boundingbox.y < boundingbox1.y)
					{
						boundingbox.y--;
					}
					
					point1.x = boundingbox.x;
					point1.y = boundingbox.y;
				}
			}
		}

		return point;
	}
}
